/*******************************************************************************
 * Copyright (c) 2011 - 2012 TXT e-solutions SpA
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * This work was performed within the IoT_at_Work Project
 * and partially funded by the European Commission's
 * 7th Framework Programme under the research area ICT-2009.1.3
 * Internet of Things and enterprise environments.
 *
 *
 * Authors:
 *     Cristoforo Seccia (TXT e-solutions SpA)
 *     Salvatore Piccione (TXT e-solutions SpA)
 *
 * Contributors:
 *      Domenico Rotondi (TXT e-solutions SpA)
 *******************************************************************************/
package it.txt.access.capability.revocation.wizard.panel.controller;

import it.txt.access.capability.commons.signer.X509DocumentSigner;
import it.txt.access.capability.commons.signer.model.X509CertificateKeyValues;
import it.txt.access.capability.commons.signer.model.X509DocumentSignerInfo;
import it.txt.access.capability.commons.signer.utils.KeystoreHelper;
import it.txt.access.capability.commons.utils.MessageUtils;
import it.txt.access.capability.revocation.CapabilityRevocationType;
import it.txt.access.capability.revocation.wizard.Wizard;
import it.txt.access.capability.revocation.wizard.WizardPanelController;
import it.txt.access.capability.revocation.wizard.panel.PanelKeystore;
import it.txt.access.capability.revocation.wizard.panel.objects.PanelAssertionObject;
import it.txt.access.capability.revocation.wizard.panel.objects.RevocationDataInsertionResultObject;

import java.awt.Component;
import java.awt.Cursor;
import java.io.File;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JOptionPane;

/**
 *
 * @author Cristoforo Seccia (TXT e-solutions SpA)
 * @author Salvatore Piccione (TXT e-solutions SpA - salvatore.piccione AT network.txtgroup.com)
 */
public class ControllerPanelKeystore extends WizardPanelController {

    private static final Logger LOGGER = Logger.getLogger(ControllerPanelAssertion.class.getName());
    private static final Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
    private static final Cursor busyCursor = new Cursor(Cursor.WAIT_CURSOR);
    private boolean isCertifiateProvided = false;
    private PanelAssertionObject forwardObject;
    private PanelKeystore panelKeystore;
    private final int completedPercentage;

    public ControllerPanelKeystore(Wizard wizard, int completedPercentage, String title) {
        super(wizard);
        panelKeystore = new PanelKeystore(title, getWizard(), this);
        this.completedPercentage = completedPercentage;
    }

    @Override
    public Component getPanelComponent() {
        return panelKeystore;
    }

    @Override
    public boolean aboutToDisplayPanel() {
        return getBackwardObject() != null && getBackwardObject() instanceof RevocationDataInsertionResultObject;
    }

    @Override
    public void displayingPanel() {
        getWizard().setBackButtonEnabled(true);
        getWizard().setNextButtonEnabled(isCertifiateProvided);
        getWizard().setFinishButtonEnabled(false);
        getWizard().setCancelButtonEnabled(true);
        getWizard().setAccessRightsCreationPercentage(completedPercentage);
        panelKeystore.validatePanelStatus();
    }

    @Override
    public boolean aboutToHidePanel() {
        if (isCertifiateProvided) {
            setForwardObject(forwardObject);
        } else {
            JOptionPane.showMessageDialog(getWizard(),
                    "Please specify your Certificate!",
                    "Capability X509 Certificate",
                    JOptionPane.ERROR_MESSAGE);
        }
        return isCertifiateProvided;
    }

    public boolean recoverAccessRightsCapabilityX509Certificate(File keystore, char[] keystorePsw, char[] certificatePsw) {

        getWizard().setCursor(busyCursor);
        isCertifiateProvided = false;
        forwardObject = new PanelAssertionObject();
        String message = "Certificate successfully acquired.";
        CapabilityRevocationType revocationToken = ((RevocationDataInsertionResultObject) getBackwardObject())
                .getCapabilityRevocation();
        String issuer = revocationToken.getIssuer().getValue();
        try {
            X509DocumentSignerInfo info = new X509DocumentSignerInfo();
            info.setKeystorePath(keystore.getPath());
            info.setKeystorePwd(keystorePsw);
            info.setPrivateKeyPwd(certificatePsw);
            info.setSignerID(issuer);
            X509CertificateKeyValues certificateKeyValues =
                    X509DocumentSigner.getCertificateKeyValues(info);
            forwardObject.setRevocationType(revocationToken);
            forwardObject.setKeyValues(certificateKeyValues);
            forwardObject.setDocumentSignerInfo(info);
            isCertifiateProvided = true;
        } catch (GeneralSecurityException ex) {
            message = ex.getMessage();
            LOGGER.log(Level.SEVERE, message, ex);
        }
        int type = isCertifiateProvided ? JOptionPane.INFORMATION_MESSAGE : JOptionPane.ERROR_MESSAGE;
        JOptionPane.showMessageDialog(getWizard(), message, "Importing certificate", type);
        getWizard().setNextButtonEnabled(isCertifiateProvided);
        getWizard().setCursor(defaultCursor);
        return isCertifiateProvided;
    }

    public String getX509CertificatePublicValuesToString() {
        StringBuilder msgs = new StringBuilder();
        if (!isCertifiateProvided) {
            msgs.append(MessageUtils.getErrorMessage("No Certificate defined", null));
            return msgs.toString();
        }
        try {
            KeyStore keyStore = KeystoreHelper.getKeyStore(
                    forwardObject.getDocumentSignerInfo().getKeystorePath(),
                    forwardObject.getDocumentSignerInfo().getKeystorePwd());
            java.security.cert.X509Certificate xc =
                    KeystoreHelper.getX509CertificateByAlias(
                    keyStore, /*"alice01"TODO RESTORE*/forwardObject.getKeyValues().getAlias());
            msgs.append(MessageUtils.getInfoMessage("Certificate Issuer DN", xc.getIssuerDN().getName()));
            msgs.append(MessageUtils.getInfoMessage("Certificate Subject DN", xc.getSubjectDN().getName()));
            msgs.append(MessageUtils.getInfoMessage("Not Before Date", xc.getNotBefore().toString()));
            msgs.append(MessageUtils.getInfoMessage("Not After Date", xc.getNotAfter().toString()));
        } catch (GeneralSecurityException ex) {
            LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
        }
        return msgs.toString();
    }
}
